<template>
    <cl-crud ref="Crud">
        <cl-row>
            <!-- 刷新按钮 -->
            <cl-refresh-btn />
            <!-- 新增按钮 -->
            <cl-add-btn />
            <!-- 删除按钮 -->
            <cl-multi-delete-btn />

            <cl-flex1 />
            <!-- 关键字搜索 -->
            <cl-search-key placeholder="搜索名称" />
        </cl-row>

        <cl-row>
            <!-- 数据表格 -->
            <cl-table ref="Table">
                <template #column-levels="{ scope }">
                    <div>
                        <build-map :levels="scope.row.levels" @open="Upsert?.close()"></build-map>
                    </div>
                </template>
            </cl-table>
        </cl-row>

        <cl-row>
            <cl-flex1 />
            <!-- 分页控件 -->
            <cl-pagination />
        </cl-row>

        <!-- 新增、编辑 -->
        <cl-upsert ref="Upsert" />
    </cl-crud>
</template>

<script lang="ts" name="game-info" setup>
import { useCrud, useTable, useUpsert } from '@cool-vue/crud';
import { useCool } from '/@/cool';
import { reactive, ref } from 'vue';
import { isArray } from 'lodash-es';
import { ElMessage } from 'element-plus';
import BuildMap from '/$/game/components/build-map/index.vue';
const { service, setRefs } = useCool();
const options = reactive({
	status: [
		{ label: '禁用', value: 0, type: 'danger' },
		{ label: '启用', value: 1, type: 'success' }
	],
	type: [
		{ label: '正常关卡', value: 0 },
		{ label: '试玩关卡', value: 1, type: 'success' }
	],
	difficulty: [
		{ label: '简单', value: 0 },
		{ label: '中等', value: 1 },
		{ label: '困难', value: 2 }
	],
	mode: [
		{ label: '数组输入', value: 0 },
		{ label: '制作地图', value: 1 }
	]
});
// cl-table
const Table = useTable({
	columns: [
		{ type: 'selection' },
		{ label: '名称', prop: 'name' },
		{ label: '下一关', prop: 'nextLevelName' },
		{ label: '难度', prop: 'difficulty', dict: options.difficulty },
		{ label: '类型', prop: 'type', dict: options.type },
		{ label: '关卡状态', prop: 'status', component: { name: 'cl-switch' } },
		{ label: '关卡地图', prop: 'levels' },
		{ label: '排序', prop: 'orderNum', width: 100, sortable: 'asc' }, //,
		{ label: '更新时间', prop: 'updateTime' },
		{ label: '创建时间', prop: 'createTime', sortable: 'asc' },
		{ type: 'op', buttons: ['edit', 'delete'] }
	]
});
// cl-upsert
const Upsert = useUpsert({
	items: [
		{
			label: '名称',
			prop: 'name',
			component: { name: 'el-input', props: { clearable: true } },
			required: false
		},
		{
			label: '排序',
			prop: 'orderNum',
			hook: 'number',
			component: { name: 'el-input-number' },
			value: 1,
			required: true
		},
		{
			label: '关卡难度',
			prop: 'difficulty',
			component: { name: 'el-select', options: options.difficulty },
			value: 0,
			required: true
		},
		{
			label: '关卡类型',
			prop: 'type',
			component: { name: 'el-select', options: options.type },
			value: 0,
			required: true
		},
		{
			label: '下一关',
			prop: 'nextLevel',
			component: { name: 'el-select', options: [] }
		},
		{
			label: '关卡状态',
			prop: 'status',
			value: 1,
			component: { name: 'cl-switch' },
			required: true
		},
		{
			label: '关卡地图',
			prop: 'levels',
			component: {
				name: 'cl-editor',
				props: {
					name: 'cl-editor-monaco',
					ref: setRefs('editor')
				}
			}
		},
		{
			label: '描述',
			prop: 'description',
			component: { name: 'el-input', props: { type: 'textarea', rows: 4 } }
		}
	],
	async onOpened(data) {
		// 设置标签列表
		if (Upsert.value?.mode == 'add') {
			service.game.info
				.page({
					page: 1,
					size: 1,
					sort: 'desc',
					order: 'orderNum'
				})
				.then((res: { list }) => {
					if (res.list.length == 0) return;
					Upsert.value?.setForm('orderNum', res.list[0].orderNum + 1);
				});
		}
		service.game.info
			.list({
				sort: 'asc',
				order: 'orderNum'
			})
			.then(res => {
				const list: any = [];
				res.forEach((e: any) => {
					if (e.orderNum > data.orderNum) {
						list.push({
							label: e.name || '',
							value: e.id
						});
					}
				});
				Upsert.value?.setOptions('nextLevel', list);
				Upsert.value?.setForm('nextLevel', list[0].value);
			});
	},
	onSubmit(data, { next, done }) {
		try {
			const levels = JSON.parse(data.levels);
			if (!checkingLevels(levels)) {
				done();
				return;
			}
			next({
				...data,
				levels: JSON.stringify(levels),
				name: data.name ? data.name : `关卡${data.orderNum}`
			});
		} catch {
			ElMessage.error('数据格式不正确');
			done();
		}
	}
});
// 验证关卡地图的参数
function checkingLevels(arr: [[number]]) {
	const rolesList: Array<number> = [19, 20]; //必须包含19,20
	const roles: Array<number> = []; //必须包含19,20
	const emenyList: Array<number> = [21, 24, 25, 44]; //至少有一个怪物
	const emeny: Array<number> = []; //至少有一个怪物
	const numberArr = [
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
		25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 39, 213, 35, 42, 44, 45, 46, 47, 48, 49, 50,
		51, 52, 53, 54, 55, 56
	];
	if (isArray(arr)) {
		for (let i = 0; i < arr.length; i++) {
			if (isArray(arr[i])) {
				for (let j = 0; j < arr[i].length; j++) {
					if (numberArr.find(item => item == arr[i][j]) == undefined) {
						ElMessage.error(`${arr[i][j]}不在地图数组中`);
						return false;
					}
					if (rolesList.find(item => item == arr[i][j])) {
						const roles_index = roles.findIndex(item => item == arr[i][j]);
						if (roles_index == -1) {
							roles.push(arr[i][j]);
						}
					}
					if (emenyList.find(item => item == arr[i][j])) {
						const emeny_index = emeny.findIndex(item => item == arr[i][j]);
						if (emeny_index == -1) {
							emeny.push(arr[i][j]);
						}
					}
				}
			} else {
				ElMessage.error('请输入正确的数组格式');
				return false;
			}
		}
	} else {
		ElMessage.error('请输入正确的数组格式');
		return false;
	}
	if (emeny.length == 0) {
		ElMessage.error('至少有一个怪物');
		return false;
	}
	if (roles.length != 2) {
		if (roles.length < 2) {
			ElMessage.error('至少有两个角色');
			return false;
		} else if (roles.length > 2) {
			ElMessage.error('最多有两个角色');
			return false;
		}
	}
	return true;
}
// cl-crud
const Crud = useCrud(
	{
		service: service.game.info
	},
	app => {
		app.refresh({ size: 50 });
	}
);

// 刷新
function refresh(params?: any) {
	Crud.value?.refresh(params);
}
</script>
